package com.andy.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.andy.dao.IExamScoreDAO;
import com.andy.dao.IExamSubjectDAO;
import com.andy.dao.IExamTestDAO;
import com.andy.dao.IExamTestTypeDAO;
import com.andy.entity.ExamScore;
import com.andy.entity.ExamSubject;
import com.andy.entity.ExamTest;
import com.andy.entity.ExamTestType;
import com.andy.utils.StringUtils;
import com.andy.utils.TestUtils;
import com.andy.vo.ExamScoreVO;
import com.andy.vo.ExamSubjectVO;
import com.andy.vo.ExamTestTypeVO;
import com.andy.vo.ExamTestVO;

@Service
@Transactional
public class TestService implements ITestService {
	
	@Autowired
	private IExamTestTypeDAO examTestTypeDAO;
	
	@Autowired
	private IExamSubjectDAO examSubjectDAO;
	
	@Autowired
	private IExamTestDAO examTestDAO;
	
	@Autowired
	private IExamScoreDAO examScoreDAO;

	@Override
	public Map<Integer, List<ExamTestVO>> getTestListBySubject(Integer subId, String userId) {
		// 初始化参数
		List<ExamTestType> testTypeList = examTestTypeDAO.loadAll();
		Map<Integer, Integer> testTypeScoreMap = new HashMap<Integer, Integer>();	// 所有题型各自的分数
		Map<Integer, List<ExamTestVO>> testListMap = new HashMap<Integer, List<ExamTestVO>>();
		// 获取所有题型，得到testTypeScoreMap
		if (testTypeList != null) {
			for (ExamTestType testType : testTypeList) {
				testTypeScoreMap.put(testType.getId(), testType.getTestTypeScore());
				// 3.0. 根据科目获取各个题型所有题目
				
				List<ExamTest> testList = examTestDAO.getTestListBySubAndTestType(subId, testType.getId());
				List<ExamTestVO> testVOList = new ArrayList<ExamTestVO>();
				
				// 分别获取各个题型在数据库里的所有题目
				for (ExamTest test : testList) {
					ExamTestVO vo = new ExamTestVO();
					BeanUtils.copyProperties(test, vo);
					
					ExamTestTypeVO testTypeVO = new ExamTestTypeVO();
					BeanUtils.copyProperties(test.getExamTestType(), testTypeVO);
					vo.setExamTestType(testTypeVO);
					testVOList.add(vo);
				}
				testListMap.put(testType.getId(), testVOList);	//　 
			}
		} else {
			return null;
		}
		
		ExamSubject subject = examSubjectDAO.get(subId);
		if (subject == null) {
			return null;
		}
		Integer totalTestScore = subject.getTotalScore().intValue();
		Integer totalTestCount = subject.getTestCount();
		
		// 1. 校验科目总分和总题数是否匹配
		if (!TestUtils.checkSubjectScoreAndCount(totalTestCount, totalTestScore, testTypeScoreMap)) {
			return null;
		}
		
		// 2. 获取各个题型的数量
		Map<Integer, Integer> testTypeCountMap = TestUtils.getTestCountByScore(totalTestCount, testTypeScoreMap);
		
		// 4. 生成随机题目
		Map<Integer, List<ExamTestVO>> resultTestListMap = new HashMap<Integer, List<ExamTestVO>>();
		for (Integer key : testTypeCountMap.keySet()) {
			Integer count = testTypeCountMap.get(key);
			List<ExamTestVO> testList = testListMap.get(key);
			// 3.1 在里面
			List<Integer> randomTestIdList = TestUtils.getRandomTestIdList(testList, count);
			if (randomTestIdList == null) {
				return null;
			}
			
			// 根据多个id获取多个题目
			List<ExamTest> randomTestList = examTestDAO.getTestListByIdList(randomTestIdList);
			
			// 转换List<ExamTest> ==>　List<ExamTestVO>
			List<ExamTestVO> testVOList = new ArrayList<ExamTestVO>();
			for (ExamTest test : randomTestList) {
				ExamTestVO vo = new ExamTestVO();
				BeanUtils.copyProperties(test, vo);
				
				ExamTestTypeVO testTypeVO = new ExamTestTypeVO();
				BeanUtils.copyProperties(test.getExamTestType(), testTypeVO);
				vo.setExamTestType(testTypeVO);
				testVOList.add(vo);
			}
			resultTestListMap.put(key, testVOList);	//　 
		}
		
		ExamScore score = new ExamScore();
		score.setUserId(userId);
		score.setSubjectId(subId);
		score.setExamTime(new Date());
		// 如果成功取到试题
		examScoreDAO.save(score);
		examScoreDAO.flush();
		
		return resultTestListMap;
	}

	@Override
	public ExamScoreVO calculateScore(List<Integer> answerIds, Map<String, String[]> testMap, String userId, Integer subId) {
		List<ExamTest> randomTestList = examTestDAO.getTestListByIdList(answerIds);
		Integer totalScore = 0;
		if (randomTestList != null) {
			for (ExamTest test : randomTestList) {
				String[] answer = testMap.get(String.valueOf(test.getId()));
				if (answer != null && test.getAnswer() != null) {
					String[] trustAnswer = test.getAnswer().split(",");
					boolean correct = StringUtils.checkStringArrayEquals(answer, trustAnswer);
					if (correct) {
						if (test.getExamTestType() != null) {
							totalScore += test.getExamTestType().getTestTypeScore();
						}
					}
				}
			}
		}
		if (userId != null && subId != null) {
			ExamScore score = examScoreDAO.getScore(userId, subId);
			if (score != null) {
				score.setScore(new BigDecimal(totalScore));
				examScoreDAO.update(score);
				examScoreDAO.flush();
				ExamScoreVO resultVO = new ExamScoreVO();
				BeanUtils.copyProperties(score, resultVO);
				return resultVO;
			}
		}
		return null;
	}

	@Override
	public ExamSubjectVO getSubjectById(Integer subId) {
		ExamSubject sub = examSubjectDAO.get(subId);
		ExamSubjectVO resultSub = new ExamSubjectVO();
		if (sub != null) {
			BeanUtils.copyProperties(sub, resultSub);
			return resultSub;
		}
		return null;
	}
	
	@Override
	public ExamScoreVO getScore(Integer subId, String userId) {
		ExamScore score = examScoreDAO.getScore(userId, subId);
		ExamScoreVO resultScore = new ExamScoreVO();
		if (score != null) {
			BeanUtils.copyProperties(score, resultScore);
			return resultScore;
		}
		return null;
	}

}
